package logica.pessoa;

import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Objeto que representa pessoas juridicas, sendo um pouco mais especifico que
 * a classe Pessoa em si.
 * @author Equipe Localisa (Usa quem precisa!)
 */
public class PessoaJuridica extends Pessoa implements Serializable{

	private transient static final long serialVersionUID = 1L;
	protected String CNPJ;
	protected String nomeFantasia;
	protected String inscricaoEstadual;
	
	public PessoaJuridica(){
		
		super ();
		this.CNPJ = null;
		this.nomeFantasia = null;
		this.inscricaoEstadual = null;
		
	}

	/**
	 * @return O CNPJ da pessoa juridica
	 */
	public String getCNPJ() {
		return CNPJ;
	}

	/**
	 * Muda o CNPJ da pessoa juridica
	 * @param cnpj O novo CNPJ
	 * @throws Exception Se o  novo CNPJ nao for valido (nao estiver
	 * de acordo com o formato especificado no sistema)
	 */
	public void setCNPJ(String cnpj) throws Exception {
		if ( ! validaCnpj(cnpj)) {
			throw new Exception("\n \t <CNPJ Invalido!>");
		}
		CNPJ = cnpj;
	}
	
	/**
	 * @return O nome de fantasia da pessoa juridica
	 */
	public String getNomeFantasia() {
		return nomeFantasia;
	}

	/**
	 * Muda o nome de fantasia da pessoa juridica
	 * @param nomeFantasia O novo nome de fantasia
	 * @throws Exception Se o novo nome de fantasia nao for valida (nao estiver
	 * de acordo com o formato especificado no sistema)
	 */
	public void setNomeFantasia(String nomeFantasia) throws Exception {
		if (! validaNomeFantasia(nomeFantasia)) {
			throw new Exception ("\n \t <Nome de Fantasia invalido!>");
		}
		this.nomeFantasia = nomeFantasia;
	}
	
	/**
	 * @return A inscricao estadual da pessoa juridica
	 */
	public String getInscricaoEstadual() {
		return inscricaoEstadual;
	}
	
	/**
	 * Muda a inscricao estadual da pessoa juridica
	 * @param inscricaoEstadual A nova inscricao estadual 
	 * @throws Exception Se a nova inscricao estadual nao for valida (nao estiver
	 * de acordo com o formato especificado no sistema)
	 */
	public void setInscricaoEstadual(String inscricaoEstadual) throws Exception {
		if (! validaInscricaoEstadual(inscricaoEstadual)) {
			throw new Exception ("\n \t <Inscricao estadual invalida!>");
		}
		this.inscricaoEstadual = inscricaoEstadual;
	}
	
	/**
	 * @return A razao social da pessoa juridica
	 */
	public String getRazaoSocial() {
		return this.getNome();
	}
	
	/**
	 * Muda a razao social da pessoa juridica
	 * @param razaoSocial A nova razao social
	 * @throws Exception Se a nova razao social nao for valida (nao estiver
	 * de acordo com o formato especificado no sistema)
	 */
	public void setRazaoSocial(String razaoSocial) throws Exception {
		setNome(razaoSocial);
	}
	
	// Valida o CNPJ, verificando se ele possui 14 digitos numericos, podendo
	// ou nao possuir um ponto depois dos dois primeiros digitos, alem de um
	// ponto apos mais 3 digitos, uma barra apos os 4 proximos digitos e um
	// hifen antes dos dois ultimos digitos
	
	private boolean validaCnpj(String cnpj) {
		if ( cnpj == null || cnpj.trim().isEmpty()) {
			return false;
		}
		
		Pattern pCnpj = Pattern.compile("[0-9]{2}([.])?[0-9]{3}([.])?[0-9]{3}([/])?[0-9]{4}([-])?[0-9]{2}");
		
		Matcher mCnpj = pCnpj.matcher(cnpj);
		
		return mCnpj.matches();
	}
	
	// Valida a inscricao estadual, verificando se a mesma possui 12
	// digitos numericos, podendo ou na possuir pontos apos os 3 primeiros
	// blocos de 3 digitos.
	
	private boolean validaInscricaoEstadual(String inscricaoEstadual) {
		if (inscricaoEstadual == null || inscricaoEstadual.trim().isEmpty()) {
			return false;
		}
		
		Pattern pInscricaoEstadual = Pattern.compile("[0-9]{3}([.])?[0-9]{3}([.])?[0-9]{3}([.])?[0-9]{3}");
		
		Matcher mInscricaoEstadual = pInscricaoEstadual.matcher(inscricaoEstadual);
		
		return mInscricaoEstadual.matches();
	}

        
	// Valida o nome de fantasia, que deve ter pelo menos 2 caracteres
	// que podem ser alfanumericos.
	
	private boolean validaNomeFantasia(String nomeFantasia) {
		if (nomeFantasia == null || nomeFantasia.trim().isEmpty()) {
			return false;
		}
		
		Pattern pNomeFantasia = Pattern.compile("([\\w]+(([\\s]*[\\w]*)?)+){2,}");
		
		Matcher mNomeFantasia = pNomeFantasia.matcher(nomeFantasia);
		
		return mNomeFantasia.matches();
	}
	
	/**
	 * Compara um objeto PessoaJuridica com um outro, verificando se
	 * seus atributos CNPJ e a Inscricao Estadual sao iguais
	 * @return True se os objetos sao iguais e False caso contrario
	 */
	
	@Override
	public boolean equals(Object object){
		if ( !(object  instanceof  Pessoa) ){
			return false;			
		}
		return (CNPJ.replace(".","").replace("/", "").replace("-", "").equals(((PessoaJuridica)object).getCNPJ().replace(".","").replace("/", "").replace("-", "")) ||
				inscricaoEstadual.replace(".", "").equals(((PessoaJuridica)object).getInscricaoEstadual().replace(".", "")));
	}
}